package com.plm.redis.crud;

import com.plm.redis.utils.RedisUtil;
import org.junit.BeforeClass;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;

/**
 * @author Limi
 * @create 2019-01-04 17:38
 */
public class TestTransaction {

    public static Jedis jedis = null;

    @BeforeClass
    public static void beforeClass(){
        jedis = RedisUtil.getJedis();
    }

    /**
     * 事务
     */
    @Test
    public void testTransaction(){
        Transaction transaction = jedis.multi();//开启事务

        transaction.set("k111", "v111");
        transaction.set("k222", "v221");

//        transaction.exec();//执行事务
        transaction.discard();//放弃事务

        List<String> mget = jedis.mget("k111", "k222");
        System.out.println(mget);
    }


    /**
     * 通俗点讲，watch命令就是标记一个键，如果标记了一个键， 在提交事务前如果该键被别人修改过，那事务就会失败，这种情况通常可以在程序中
     * 重新再尝试一次。
     * 首先标记了键balance，然后检查余额是否足够，不足就取消标记，并不做扣减； 足够的话，就启动事务进行更新操作，
     * 如果在此期间键balance被其它人修改， 那在提交事务（执行exec）时就会报错， 程序中通常可以捕获这类错误再重新执行一次，直到成功。
     */
    @Test
    public void testTransactionTrade() throws InterruptedException {
        int balance;// 可用余额
        int debt;// 欠额
        int amtToSubtract = 10;// 实刷额度

        jedis.watch("balance");
        Thread.sleep(10000);
        balance = Integer.parseInt(jedis.get("balance"));
        if (balance < amtToSubtract) {
            jedis.unwatch();
            System.out.println("额度不够......");
        } else {
            Transaction transaction = jedis.multi();

            transaction.decrBy("balance", amtToSubtract);//花呗额度减去交易额
            transaction.incrBy("debt", amtToSubtract);//债务加上交易额

            transaction.exec();
            debt = Integer.parseInt(jedis.get("debt"));
            balance = Integer.parseInt(jedis.get("balance"));

            System.out.println("花呗额度：" + balance);
            System.out.println("透支额度：" + debt);
        }
    }

    @Test
    public void test(){
        String balance = jedis.watch("balance");
        System.out.println(balance);

    }

}
